<?php


namespace common\service;


use common\exception\LogicException;
use common\model\ChatModel;
use common\model\ChatUserModel;
use common\model\UrgeMessageMemberModel;
use common\model\UrgeMessageModel;
use common\model\UserModel;
use support\ErrorCode;
use support\SingletonTrait;
use teamones\Request;
use think\Cache;
use think\Exception;
use Webman\Stomp\Client;


class UrgeMessageService
{
    use SingletonTrait;

    public function create($data, $currentUserId)
    {
        //催一催记录创建
        $userIds = $data['user_ids'];
        $source = $data['source'];
        unset($data['user_ids'], $data['source']);

        //参数验证判定
        if ($source['type'] == "group" && empty($source['chat_global_id'])) {
            throw new LogicException('source chat_global_id not exist', ErrorCode::REQUEST_PARAM_ERROR);
        }
        $urgeMessageModel = model(UrgeMessageModel::class);
        $urgeMessageResult = [];
        $urgeMessageModel->startTrans();
        try {
            $urgeMessageResult = $urgeMessageModel->addItem($data);

            //组装成员数据
            $urgeMessageMember = [];
            if (!$urgeMessageResult) {
                throw new LogicException('add urge message failure', ErrorCode::ADD_URGE_MESSAGE_FAILURE);
            }
            $urgeMessageMember[] = [
                'urge_message_id' => $urgeMessageResult['id'],
                'user_id' => $currentUserId,
                'is_sender' => 1,
                'created' => time()
            ];

            foreach ($userIds as $userId) {
                $urgeMessageMember[] = [
                    'urge_message_id' => $urgeMessageResult['id'],
                    'user_id' => $userId,
                    'is_sender' => 0,
                    'created' => time()
                ];
            }
            //添加成员
            model(UrgeMessageMemberModel::class)->addAll($urgeMessageMember);
            $urgeMessageModel->commit();
        } catch (\Throwable $e) {
            $urgeMessageModel->rollback();
            throw $e;
        }


        //需要判定来源 - 单聊,群聊
        //单聊查找到会话,没有会话则需要新建会话
        //自己不能给自己发送催一催,系统内没法自己给自己对话
        $chatIds = [];
        $sourceType = $source['type'];
        $chatReceivers = [];
        $isSendChat = false;

        //发送消息到群里的用户
        $sendChatUserIds = array_filter($userIds, function ($userId) use ($currentUserId) {
            return $userId != $currentUserId;
        });

        switch ($sourceType) {
            case "one2one":
                $chat = ChatService::getInstance()->getOneToOneChatList($sendChatUserIds, $currentUserId);
                $chatIds = array_column($chat, 'global_id');
                $chatUsers = model(ChatUserModel::class)
                    ->where(['chat_global_id' => ["IN", $chatIds], "user_id" => $currentUserId, "is_leave" => "no"])
                    ->field("chat_global_id,to_user_id")->select();

                foreach ($chatUsers as $chatUser) {
                    $chatReceivers[$chatUser['chat_global_id']] = [$chatUser['to_user_id']];
                }
                $isSendChat = true;
                break;
            case "group":
                $chatIds = [$source['chat_global_id']];
                $chatReceivers[$source['chat_global_id']] = $sendChatUserIds;
                $isSendChat = true;
                break;
        }

        //消息同步 , 追加 催一催记录id
        $urgeMessageResultContent = json_decode($urgeMessageResult['content'], true);
        $content = $urgeMessageResultContent;
        $content['urge_message_id'] = $urgeMessageResult['id'];
        $messageData = [
            "content_type" => "urge",
            'content' => $content,
            'sender' => $currentUserId,
            'send_at' => $urgeMessageResult['created']
        ];

        //是否发送到群里
        $messageService = MessageService::getInstance();
        if ($isSendChat) {
            //发送消息到群里
            $messages = $messageService->batchPushUrgeMessage($chatIds, $chatReceivers, $currentUserId, $messageData);

            //回填到催一催
            //比对chat_global_id 过滤掉未发送到群的
            $diffChatReceivers = array_intersect_key($chatReceivers, $messages);

            if (!empty($diffChatReceivers)) {
                //找出接收者人员
                $chatReceiverIds = [];
                foreach ($diffChatReceivers as $diffChatReceiver) {
                    $chatReceiverIds = array_merge($chatReceiverIds, $diffChatReceiver);
                }

                //找到相关的催一催记录人员
                $chatReceiverIds[] = $currentUserId;
                $urgeMessageMemberList = model(UrgeMessageMemberModel::class)->where(['user_id' => ["IN", $chatReceiverIds], 'urge_message_id' => $urgeMessageResult['id']])->select();

                //群聊与单聊的回填不同
                if (!empty($urgeMessageMemberList)) {
                    switch ($sourceType) {
                        case "one2one":
                            $diffChatReceivers = array_flip(array_map(function ($diffChatReceiver) {
                                return $diffChatReceiver[0];
                            }, $diffChatReceivers));

                            $updateUrgeMessageMemberData = [];
                            foreach ($urgeMessageMemberList as $urgeMessageMemberItem) {
                                $urgeMessageMemberParam = json_decode($urgeMessageMemberItem['param'], true) ?? [];
                                if ($urgeMessageMemberItem['user_id'] == $currentUserId && !empty($source['chat_global_id']) && isset($messages[$source['chat_global_id']])) {
                                    $urgeMessageMemberParam = array_merge($urgeMessageMemberParam, ["chat_global_id" => $source['chat_global_id'], "message_id" => $messages[$source['chat_global_id']]['id']]);
                                    //自身单独处理
                                    $updateUrgeMessageMemberData[] = [
                                        'id' => $urgeMessageMemberItem['id'],
                                        'param' => json_encode($urgeMessageMemberParam)
                                    ];
                                } elseif (isset($diffChatReceivers[$urgeMessageMemberItem['user_id']]) && isset($messages[$diffChatReceivers[$urgeMessageMemberItem['user_id']]])) {
                                    $currentMessage = $messages[$diffChatReceivers[$urgeMessageMemberItem['user_id']]];
                                    $urgeMessageMemberParam = array_merge($urgeMessageMemberParam, ["chat_global_id" => $currentMessage['chat_global_id'], "message_id" => $currentMessage['id']]);
                                    $updateUrgeMessageMemberData[] = [
                                        'id' => $urgeMessageMemberItem['id'],
                                        'param' => json_encode($urgeMessageMemberParam)
                                    ];
                                }
                            }

                            if (!empty($updateUrgeMessageMemberData)) {
                                model(UrgeMessageMemberModel::class)->saveAll($updateUrgeMessageMemberData);
                            }

                            break;
                        case "group":
                            $urgeMessageMemberIds = array_column($urgeMessageMemberList, 'id');
                            $urgeMessageMemberIds = join(",", $urgeMessageMemberIds);
                            $currentMessage = array_values($messages)[0];
                            model(UrgeMessageMemberModel::class)
                                ->execute("update urge_message_member set param = JSON_SET(IFNULL(param,'{}'),'$.chat_global_id','{$currentMessage['chat_global_id']}','$.message_id',{$currentMessage['id']}) where id in ({$urgeMessageMemberIds})");
                            model(UrgeMessageMemberModel::class)->where(["id" => ["IN", $urgeMessageMemberIds]])->save();
                            break;
                    }
                }
            }
        }

        //判定催一催类型,找到渲染模板
        $optionsService = OptionsService::getInstance();
        $isSendMsm = false;
        switch ($urgeMessageResult['type']) {
            case "app":
                $rendMessageTemplateName = "app_urge_notify_template_id";
                break;
            case "sms":
                $rendMessageTemplateName = "sms_urge_notify_template_id";
                $isSendMsm = true;
                break;
            default:
                $rendMessageTemplateName = "app_urge_notify_template_id";
        }

        //模板渲染,弹窗推送
        $rendMessageTemplateId = $optionsService->getOptionsConfigItemData("message_notify_template_config", $rendMessageTemplateName);
        $currentUser = model(UserModel::class)->field("name")->find($currentUserId);
        //暂时只弹窗文字
        $messageParam = [
            'first' => $urgeMessageResultContent['content'],
            'keyword1' => $currentUser['name'],
        ];
        $actions = [
            [
                'key' => "see_urge_message_details",
                'text' => '立即查看',
                'param' => null
            ],
            [
                'key' => "ignore_urge_message",
                'text' => '忽略',
                'param' => null
            ],
        ];
        $systemNotifyMessageData = [
            "param" => $messageParam,
            "receiver" => $userIds,
            "template_id" => $rendMessageTemplateId,
            "content_type" => $messageData['content_type'],
            "actions" => $actions,
            "notice_type" => "urge",
            "message_key" => $urgeMessageResult['type'] . "_urge",
            "is_popup" => true,
            "notify_user_mark" => "producer_assistant",
            "extra_data" => [
                'urge_message_id' => $urgeMessageResult['id'],
            ],
        ];
        $messageService->sendSystemNotifyMessage($systemNotifyMessageData);
        //短信类型需要发送短信
        if ($isSendMsm) {
            $this->notifyUrgeMessage($userIds, $currentUserId, $urgeMessageResultContent['content']);
        }
        return $urgeMessageResult;
    }

    /**
     * 催一催短信通知
     * @param $userIds
     * @param $sender
     * @param $content
     * @throws Exception
     */
    public function notifyUrgeMessage($userIds, $sender, $content)
    {
        //短信限制个数
        $urgeMessageLimit = "urge_message_limit:sender_{$sender}";
        $limit = 50;
        $urgeMessageLimitData = Cache::get($urgeMessageLimit);
        if ($urgeMessageLimitData === false) {
            //当前剩余时间 ,到明天0点 失效
            $expireTime = strtotime('tomorrow') - time();
            Cache::set($urgeMessageLimit, $limit - 1, $expireTime); //到明天0点剩余时间
        } else if ($urgeMessageLimitData > 0) {
            Cache::dec($urgeMessageLimit);
        } else {
            throw new LogicException('urge message sms exceed the limit', ErrorCode::URGE_MESSAGE_SMS_EXCEED_THE_LIMIT);
        }

        $dataList = [];
        $userData = $userIds;
        $userData[] = $sender;
        $userData = array_unique($userData);
        $user = model(UserModel::class)->where(['id' => ["IN", $userData]])->field("id,name,phone")->select();
        $phoneList = array_column($user, null, 'id');
        $senderName = $phoneList[$sender]['name'];
        if (!in_array($sender, $userIds)) {
            unset($phoneList[$sender]);
        }

        //限制四十个字符
        if (mb_strlen($content, "utf-8") > 40) {
            $content = mb_substr($content, 0, 39, 'utf-8') . "...";
        }

        foreach ($phoneList as $phone) {
            $dataList[] = [
                'phone' => $phone['phone'],
                'template' => 'urge_message_notify_receiver',
                'data' => [
                    $senderName,
                    $content
                ]
            ];
        }

        Request::connection()
            ->setHeader([
                'X-Userinfo' => request()->getXUserInfo(),
            ])
            ->setServerHost('teamones-oauth')
            ->setRoute('sms/batch_send')
            ->setBody([
                'data_list' => $dataList
            ])
            ->setMethod('POST')
            ->request();
    }

    /**
     * 获取催一催列表
     * @param $param
     * @param $currentUserId
     * @return array
     * @throws \Exception
     */
    public function getList($param, $currentUserId)
    {
        $order = $param['order'] ?? "id desc";
        $page = $param['page'] ?? [1, C("database.database_max_select_rows")];
        $urgeMessageMemberList = model(UrgeMessageMemberModel::class)
            ->where($param['filter'])
            ->where(["user_id" => $currentUserId])->page(...$page)->order($order)->select();

        $urgeMessageIds = [];
        $senderUrgeMessageIds = [];
        $receiverUrgeMessageIds = [];
        foreach ($urgeMessageMemberList as $urgeMessageMemberItem) {
            $urgeMessageIds[$urgeMessageMemberItem["urge_message_id"]] = $urgeMessageMemberItem["urge_message_id"];
            if ($urgeMessageMemberItem["is_sender"] === 1) {
                $senderUrgeMessageIds[] = $urgeMessageMemberItem["urge_message_id"];
            } else {
                $receiverUrgeMessageIds[] = $urgeMessageMemberItem["urge_message_id"];
            }
        }

        $urgeMessageIds = array_values($urgeMessageIds);

        if (empty($urgeMessageIds)) {
            return [];
        }

        //追加记录内容
        $urgeMessageList = model(UrgeMessageModel::class)->where(['id' => ["IN", $urgeMessageIds]])->select();
        $urgeMessageList = array_map(function ($urgeMessageItem) {
            $urgeMessageItem["content"] = json_decode($urgeMessageItem["content"], true);
            return $urgeMessageItem;
        }, $urgeMessageList);

        $urgeMessageList = array_column($urgeMessageList, null, 'id');
        //判定是否是发送者,如果是发送者,可以查看,接收人员名,以及个数
        $urgeMessageMemberReceiverGroup = [];
        if (!empty($senderUrgeMessageIds)) {
            $urgeMessageMemberReceiverGroup = $this->getUrgeMessageMemberReceiverGroup($senderUrgeMessageIds);
        }

        //如果是接收者,可以查看发送者头像
        $urgeMessageMemberSenderUserMap = [];
        $urgeMessageMemberSenderUserInfo = [];
        if (!empty($receiverUrgeMessageIds)) {
            $urgeMessageMemberSender = model(UrgeMessageMemberModel::class)
                ->where(['urge_message_id' => ["IN", $receiverUrgeMessageIds], 'is_sender' => 1])->field("id,urge_message_id,user_id,is_read")->select();
            $urgeMessageMemberSenderUserMap = array_column($urgeMessageMemberSender, 'user_id', 'urge_message_id');
            $urgeMessageMemberSenderUserIds = array_unique(array_column($urgeMessageMemberSender, 'user_id'));
            $urgeMessageMemberSenderUserInfo = MessageService::getInstance()->getChatUserInfo($urgeMessageMemberSenderUserIds);
            $urgeMessageMemberSenderUserInfo = array_column($urgeMessageMemberSenderUserInfo, null, 'id');
        }

        //追加会话
        $chatGlobalIds = [];
        foreach ($urgeMessageMemberList as $urgeMessageMemberItem) {
            $urgeMessageMemberItemParam = json_decode($urgeMessageMemberItem['param'], true);
            if (!empty($urgeMessageMemberItemParam['chat_global_id'])) {
                $chatGlobalIds[$urgeMessageMemberItemParam['chat_global_id']] = $urgeMessageMemberItemParam['chat_global_id'];
            }
        }

        $chatGlobalIds = array_values($chatGlobalIds);

        $chat = [];
        if (!empty($chatGlobalIds)) {
            $chat = model(ChatModel::class)->where(['global_id' => ["IN", $chatGlobalIds]])->field("name,global_id")->select();
            $chat = array_column($chat, null, 'global_id');
        }

        //组装数据
        $urgeMessageMemberList = array_map(function ($urgeMessageMemberItem) use (
            $chat, $urgeMessageMemberReceiverGroup, $urgeMessageMemberSenderUserMap, $urgeMessageMemberSenderUserInfo, $urgeMessageList
        ) {
            if ($urgeMessageMemberItem["is_sender"] === 1) {
                if (isset($urgeMessageMemberReceiverGroup[$urgeMessageMemberItem['urge_message_id']])) {
                    $urgeMessageMemberItem['receiver'] = $urgeMessageMemberReceiverGroup[$urgeMessageMemberItem['urge_message_id']];
                }
            } else {
                if (!empty($urgeMessageMemberSenderUserMap[$urgeMessageMemberItem['urge_message_id']]) &&
                    !empty($urgeMessageMemberSenderUserInfo[$urgeMessageMemberSenderUserMap[$urgeMessageMemberItem['urge_message_id']]])
                ) {
                    $urgeMessageMemberItem['sender'] = $urgeMessageMemberSenderUserInfo[$urgeMessageMemberSenderUserMap[$urgeMessageMemberItem['urge_message_id']]];
                }
            }
            $urgeMessageMemberItem['param'] = json_decode($urgeMessageMemberItem['param'], true);
            $urgeMessageMemberItem['chat'] = null;
            if (!empty($urgeMessageMemberItem['param']['chat_global_id']) && isset($chat[$urgeMessageMemberItem['param']['chat_global_id']])) {
                $urgeMessageMemberItem['chat'] = $chat[$urgeMessageMemberItem['param']['chat_global_id']];
            }

            if (!empty($urgeMessageList[$urgeMessageMemberItem['urge_message_id']])) {
                $urgeMessageMemberItem['urge_message'] = $urgeMessageList[$urgeMessageMemberItem['urge_message_id']];
            }
            return $urgeMessageMemberItem;
        }, $urgeMessageMemberList);

        return $urgeMessageMemberList;
    }

    /**
     * 催一催接收者组
     * @param $senderUrgeMessageIds
     * @return array
     */
    public function getUrgeMessageMemberReceiverGroup($senderUrgeMessageIds)
    {
        $urgeMessageMemberReceiver = model(UrgeMessageMemberModel::class)
            ->where(['urge_message_id' => ["IN", $senderUrgeMessageIds], 'is_sender' => 0])->field("id,urge_message_id,user_id,is_read")->select();

        if (empty($urgeMessageMemberReceiver)) {
            return [];
        }

        $urgeMessageMemberReceiverUserIds = array_unique(array_column($urgeMessageMemberReceiver, 'user_id'));
        $userInfo = model(UserModel::class)->where(["id" => ["IN", $urgeMessageMemberReceiverUserIds]])->field("id,name")->select();
        $userInfo = array_column($userInfo, null, 'id');

        $urgeMessageMemberReceiver = array_map(function ($urgeMessageMemberReceiverItem) use ($userInfo) {
            $urgeMessageMemberReceiverItem['user_info'] = $userInfo[$urgeMessageMemberReceiverItem['user_id']] ?? null;
            return $urgeMessageMemberReceiverItem;
        }, $urgeMessageMemberReceiver);

        $urgeMessageMemberReceiverGroup = array_group_by($urgeMessageMemberReceiver, 'urge_message_id');
        return $urgeMessageMemberReceiverGroup;
    }

    /**
     * 催一催已读触发
     * @param $urgeMessageId
     * @param $currentUserId
     * @return array|bool|int|string
     * @throws Exception
     */
    public function updateUrgeMessageRead($urgeMessageId, $currentUserId)
    {
        $urgeMessageMember = model(UrgeMessageMemberModel::class)->where(['urge_message_id' => $urgeMessageId, 'user_id' => $currentUserId])->find();
        $urgeMessageMemberData = [];
        if (!empty($urgeMessageMember)) {
            $urgeMessageMemberData = model(UrgeMessageMemberModel::class)->save([
                'id' => $urgeMessageMember['id'],
                'is_read' => 1
            ]);

            if (!$urgeMessageMemberData) {
                return $urgeMessageMemberData;
            }

            //查找发送者
            $urgeMessageMemberList = model(UrgeMessageMemberModel::class)->where(['urge_message_id' => $urgeMessageMember["urge_message_id"]])->select();
            $sender = 0;
            $receivers = [];
            foreach ($urgeMessageMemberList as $urgeMessageMemberItem) {
                $receivers[] = $urgeMessageMemberItem['user_id'];
                if ($urgeMessageMemberItem['is_sender'] == 1) {
                    $sender = $urgeMessageMemberItem['user_id'];
                }
            }

            //需要给催一催记录内容所有的接收发送一遍
            $content = json_decode($urgeMessageMember['param'], true);

            if (!empty($content['chat_global_id']) && !empty($content['message_id'])) {
                $this->pushSystemUrgeMessageHit($content['chat_global_id'], $sender, $currentUserId, $receivers, $urgeMessageMember["urge_message_id"], $content['message_id']);
            }
        }
        return $urgeMessageMemberData;
    }

    /**
     * 推送系统催一催提示
     * @param $chatGlobalId
     * @param $sender
     * @param $receiver
     * @param $receivers
     * @param $urgeMessageId
     * @param $messageId
     * @throws \Exception
     */
    public function pushSystemUrgeMessageHit($chatGlobalId, $sender, $receiver, $receivers, $urgeMessageId, $messageId)
    {
        if (!empty($receivers)) {
            $receiverList = model(UserModel::class)->where(['id' => ["IN", $receivers]])->field('id,name,channel')->select();
            $receiverList = array_column($receiverList, null, 'id');
            $sender = $receiverList[$sender];
            $receiver = $receiverList[$receiver];
            $chat = ChatService::getInstance()->getChatDetail(['global_id' => $chatGlobalId]);

            //判定单聊还是群聊
            if ($chat == "group") {
                $receiveUserChat = model(ChatUserModel::class)
                    ->alias('cu')
                    ->join('user AS u ON cu.user_id = u.id', "LEFT")
                    ->field('cu.user_id,u.channel,u.id')
                    ->where([
                        'cu.chat_global_id' => $chatGlobalId,
                        'cu.is_leave' => "no"
                    ])->select();

                $userIds = array_column($receiveUserChat, 'user_id');
                $userAvatar = MessageService::getInstance()->getChatUserInfo(array_slice($userIds, 0, 9, false));
                $chat['avatar'] = array_column($userAvatar, 'thumb');
                foreach ($userAvatar as $userAvatarItem) {
                    $chat['chat_icon_data'][] = [
                        "id" => $userAvatarItem['id'],
                        "name" => $userAvatarItem['name'],
                        "avatar" => $userAvatarItem['thumb']
                    ];
                }
                $chat['count'] = count($receiveUserChat);
                $receiveUserChat = array_column($receiveUserChat, null, 'id');

                //比对出只需要发送的
                $receiveUserChat = array_intersect_key($receiveUserChat, $receiverList);
                $receiveUserChat = array_values($receiveUserChat);
            } else {
                //单聊发送接收方和发送方
                $receiveUserChat = [
                    ['id' => $sender['id'], 'channel' => $sender['channel']],
                    ['id' => $receiver['id'], 'channel' => $receiver['channel']],
                ];
            }

            unset($sender['channel'], $receiver['channel']);


            $tmpMessage = [
                "chat_global_id" => $chatGlobalId,
                "type" => 'normal',
                'sender' => 0,
                'project_id' => 0,
                "content_type" => 'system_hint',
                "content" => [
                    "type" => "urge_read",
                    "replace" => [
                        "sender" => $sender,
                        "receiver" => $receiver,
                        'urge_message_id' => $urgeMessageId,
                        'message_id' => $messageId
                    ]
                ]
            ];
            $queueData = [
                'chat_global_id' => $chat['global_id'],
                'message' => $tmpMessage,
                'user_id_list' => array_column($receiveUserChat, 'id'),
            ];
            Client::send('send_system_hit_message', build_queue_data_with_xu($queueData));
        }
    }

    /**
     * 更新催一催
     * @param $data
     * @return array|bool|int|string
     * @throws \Exception
     */
    public function updateUrgeMessageMember($data)
    {
        $urgeMessageMemberList = model(UrgeMessageMemberModel::class)->where([
            'urge_message_id' => $data['urge_message_id'],
            'user_id' => $data['user_id']
        ])->select();

        unset($data['urge_message_id'], $data['user_id']);
        $urgeMessageMemberIds = array_column($urgeMessageMemberList, 'id');
        if (empty($urgeMessageMemberIds)) {
            return [];
        }
        return model(UrgeMessageMemberModel::class)->where(['id' => ["IN", $urgeMessageMemberIds]])->save($data);
    }
}
